#include <SDL/SDL_image.h>
#include "MainWindow.h"
#include "Gomoku.h"
#include "Board.h"
#include "PieceSelector.h"
#include "UIBoard.h"

UIBoard::UIBoard(Sint16 _x, Sint16 _y)
: m_cleaner(_x, _y), m_canMovePieces(false), m_canRemovePieces(true), m_canRemove(true)
{
	m_pieces = new Image[COLOR_COUNT];
	
	m_pieces[COLOR_NONE].Surface = IMG_Load("images\\SelectedPiece.png");
	m_pieces[COLOR_NONE].setTransparence();
	m_pieces[COLOR_BLACK].Surface = IMG_Load("images\\BlackPiece.png");
	m_pieces[COLOR_BLACK].setTransparence();
	m_pieces[COLOR_WHITE].Surface = IMG_Load("images\\WhitePiece.png");
	m_pieces[COLOR_WHITE].setTransparence();

	m_background.Surface = IMG_Load("images\\Board.png");
	m_cleaner.Surface = SDL_CreateRGBSurface(SDL_HWSURFACE, m_background.Surface->w, m_background.Surface->h, 32, 0, 0, 0, 0);
	SDL_FillRect(m_cleaner.Surface, NULL, 0);
}

UIBoard::~UIBoard()
{
	delete [] m_pieces;
}

bool UIBoard::draw()
{
	SDL_Surface* screen = MainWindow::Screen();
	BoardCase** cases = Gomoku::Instance().Board.Cases;
	
	SDL_BlitSurface(m_cleaner.Surface, NULL, screen, &m_cleaner.Position);
	SDL_BlitSurface(m_background.Surface, NULL, m_cleaner.Surface, NULL);
	m_positions.clear();
	for (BoardCase y = 0; y < Board::HEIGHT; y++)
	{
		for (BoardCase x = 0; x < Board::WIDTH; x++)
		{
			if (GET_COLOR(cases[y][x]) != COLOR_NONE)
			{
				SDL_Rect pos = {
						16 + (x * m_pieces[0].Surface->w) - m_pieces[0].Surface->w / 2,
						16 + (y * m_pieces[0].Surface->h) - m_pieces[0].Surface->h / 2,
						0,
						0
				};
				if (PieceSelector::Instance().SelectedPiece != NULL)
				{
					if (pos.x == PieceSelector::Instance().SelectedPosition.x && pos.y == PieceSelector::Instance().SelectedPosition.y)
					{
						SDL_BlitSurface(m_pieces[COLOR_NONE].Surface, NULL, m_cleaner.Surface, &pos);
					}
					else
					{
						m_positions.push_back(pos);
						SDL_BlitSurface(m_pieces[GET_COLOR(cases[y][x])].Surface, NULL, m_cleaner.Surface, &pos);
					}
					PieceSelector::Instance().draw(m_cleaner.Surface);
				}
				else
				{
					m_positions.push_back(pos);
					SDL_BlitSurface(m_pieces[GET_COLOR(cases[y][x])].Surface, NULL, m_cleaner.Surface, &pos);
				}
			}
		}
	}
	return (true);
}

static SDL_Rect const* checkIfCursorIsOnPlayerCase(int _x, int _y, std::vector<SDL_Rect> const& _positions, SDL_Surface* _piece)
{
	std::vector<SDL_Rect>::const_iterator it = _positions.begin();
	for (; it != _positions.end(); ++it)
	{
		bool cond_x = (_x > it->x + _piece->w / 2 && _x < it->x + _piece->w / 2 + _piece->w);
		bool cond_y = (_y > it->y + _piece->h / 2 && _y < it->y + _piece->h / 2 + _piece->h);
		if (cond_x && cond_y)
			return (&(*it));
	}
	return (NULL);
}

void UIBoard::leftClickEvent(SDL_Event& _e, int _x, int _y)
{
	bool piece_found = false;
	int case_y = (_y - 16) / 32;
	int case_x = (_x - 16) / 32;
	if (case_x >= Board::WIDTH || case_y >= Board::HEIGHT)
		return ;
	if (m_canMovePieces == true)
	{
		SDL_Rect const* pos = checkIfCursorIsOnPlayerCase(_x, _y, m_positions, m_pieces[0].Surface);
		if (pos != NULL)
		{
				BoardCase& tmp = Gomoku::Instance().Board.Cases[case_y][case_x];
				unsigned char color = GET_COLOR(tmp);
				Image* piece = &m_pieces[GET_COLOR(color)];
				piece->Position = *pos;
				PieceSelector::Instance().SelectedPiece = piece;
				PieceSelector::Instance().setBoardPosition(case_x, case_y);
				PieceSelector::Instance().CaseBackup = tmp;
				Board::CreateNewBoardCase(tmp, COLOR_NONE,
					CONVERT_POSITION_X(GET_POSITION_X(tmp)), CONVERT_POSITION_Y(GET_POSITION_Y(tmp)),
					GET_ALIGN_ENMY(tmp), GET_ALIGN_ALLY(tmp), GET_SURROUNDED(tmp));
				//Board::ClearCase(Gomoku::Instance().Board.Cases[case_x][case_y], case_x, case_y);
				Gomoku::Instance().Board.Cases[case_y][case_x] = color;
				_e.type = SDL_MOUSEMOTION;
				SDL_PushEvent(&_e);
		}
	}
	if (piece_found == false || m_canMovePieces == false)
	{
		if (Gomoku::Instance().Board.CanIMove(case_x, case_y, Gomoku::Instance().CurrentPlayer->Color, true) == true)
		{
			Gomoku& gomoku = Gomoku::Instance();
			gomoku.Board.CapturePieces(gomoku.Board.Cases[case_y][case_x]);
			if (gomoku.Arbiter.HasCurrentPlayerWon() == true)
			{
				gomoku.getPlayers()[GET_COLOR(gomoku.Board.Cases[case_y][case_x])].Winner = true;
				gomoku.Arbiter.SetCurrentPlayerWin(false);
			}
			//if (Gomoku::Instance().CurrentPlayer->Winner == false)
			Gomoku::Instance().nextPlayerTurn();
		}
	}
	_e.type = SDL_MOUSEMOTION;
	SDL_PushEvent(&_e);
}

void UIBoard::rightClickEvent(SDL_Event& _e, int _x, int _y)
{
	int case_y = (_y - 16) / 32;
	int case_x = (_x - 16) / 32;
	if (case_x >= Board::WIDTH || case_y >= Board::HEIGHT)
		return ;
	Board::PrintCase(Gomoku::Instance().Board.Cases[case_y][case_x]/*, case_x, case_y*/);
	_e.type = SDL_MOUSEMOTION;
	SDL_PushEvent(&_e);
}

void UIBoard::middleClickEvent(SDL_Event& _e, int _x, int _y)
{
	if (m_canRemovePieces == false || m_canRemove == false)
		return ;
	int case_y = (_y - 16) / 32;
	int case_x = (_x - 16) / 32;
	if (case_x >= Board::WIDTH || case_y >= Board::HEIGHT)
		return ;
	SDL_Rect const* pos = checkIfCursorIsOnPlayerCase(_x, _y, m_positions, m_pieces[0].Surface);
	if (pos != NULL)
	{
		Gomoku::Instance().Board.ClearCase(Gomoku::Instance().Board.Cases[case_y][case_x], case_x, case_y);
		_e.type = SDL_MOUSEMOTION;
		SDL_PushEvent(&_e);
	}
}

void UIBoard::doEvents()
{
	SDL_Event& e = MainWindow::Event();

	if (PieceSelector::Instance().SelectedPiece == NULL || m_canMovePieces == false)
	{
		int x = 0, y = 0;
		Uint8 mouseState = SDL_GetMouseState(&x, &y);
		if (e.type == SDL_MOUSEBUTTONUP)
		{
			if (e.button.button == SDL_BUTTON_LEFT)
				this->leftClickEvent(e, x, y);
			else if (e.button.button == SDL_BUTTON_RIGHT)
				this->rightClickEvent(e, x, y);
			else if (e.button.button == SDL_BUTTON_MIDDLE)
				this->middleClickEvent(e, x, y);
		}
	}
	else
	{
		PieceSelector::Instance().doEvents();
	}
}

void UIBoard::setCanMovePieces(bool _value)
{
	m_canMovePieces = _value;
}

void UIBoard::setCanRemovePieces(bool _value)
{
	m_canRemovePieces = _value;
}

Image* UIBoard::getPiece(unsigned char _color)
{
	if (_color == COLOR_BLACK || _color == COLOR_WHITE)
		return (&m_pieces[_color]);
	return (NULL);
}

SDL_Surface* UIBoard::getBackground()
{
	return (m_background.Surface);
}

void UIBoard::setCanRemove(bool _value)
{
	m_canRemove = _value;
}
